/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * callbacks.c
 * Copyright (C) Kevin DeKorte 2009 <kdekorte@gmail.com>
 * 
 * Fosfor is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Fosfor is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gst/interfaces/navigation.h>

#include "callbacks.h"
#include "support.h"

gboolean get_playing(GstElement *element)
{
	GstState state, pending;
	gboolean playing;
	
	gst_element_get_state (element, &state, &pending, 0);
  
	if (pending)
		playing = (pending == GST_STATE_PLAYING);
	else
		playing = (state == GST_STATE_PLAYING);

	return playing;
}

void set_playing(GstElement *element, gboolean playing)
{
	GstState state = GST_STATE_PAUSED;

	if (playing)
		state = GST_STATE_PLAYING;

	gst_element_set_state(element, state);
	g_object_notify (G_OBJECT(media), "playing");
	g_object_notify (G_OBJECT(media), "progress");	
}

gdouble get_progress(GstElement *element)
{   
	GstQuery *query;
	gdouble position = 0.0, length = 0.0;
	gint64 value;
	
	query = gst_query_new_duration(GST_FORMAT_TIME);
	if (gst_element_query(element, query)) {
		gst_query_parse_duration(query, NULL, &value);
		length = (gdouble)value / GST_SECOND;
	}
	gst_query_unref(query);
	
	query = gst_query_new_position(GST_FORMAT_TIME);
	if (gst_element_query(element, query)) {
		gst_query_parse_position(query, NULL, &value);
		position = (gdouble)value / GST_SECOND;
	}
	gst_query_unref(query);

	return CLAMP ((gdouble) position / (gdouble) length, 0.0, 1.0);
}	

void set_progress(GstElement *element, gdouble progress)
{
	GstQuery *query;
	gint64 value;
	GstState state, pending;
	
	gst_element_get_state (element, &state, &pending, 0);

	if (pending)
		state = pending;

	gst_element_set_state (element, GST_STATE_PAUSED);

	
	query = gst_query_new_duration(GST_FORMAT_TIME);
	if (gst_element_query(element, query)) {
		gst_query_parse_duration(query, NULL, &value);
	}
	gst_query_unref(query);
	
	value = progress * value;

	gst_element_seek(element, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, value, 0,0);
	
	gst_element_set_state (element, state);
	g_object_notify (G_OBJECT(media), "progress");	
}


void destroy (GtkWidget *widget, gpointer data)
{
	// gtk_main_quit ();
}


gboolean resize_window(gpointer data)
{
	GList *l;
	ListItem *i;
	GTimeVal currenttime;
	
	//printf("resize window %i x %i\n",video_width,video_height);

	g_get_current_time(&currenttime);
    last_movement_time = currenttime.tv_sec;
	
	if (window_width > 0 && window_height > 0) {
			gtk_widget_show(GTK_WIDGET(clutter));
			gtk_widget_show(GTK_WIDGET(fixed));
			gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, TRUE);
			if (video_width > 0 && video_height > 0) {
				fosfor_button_set_sensitive(FOSFOR_BUTTON(cfullscreen), TRUE);
			} else {
				fosfor_button_set_sensitive(FOSFOR_BUTTON(cfullscreen), FALSE);
			}		
			gtk_window_resize(GTK_WINDOW(window),window_width, window_height);
	} else {
		if (video_width > 0 && video_height > 0) {
			for(l = playlist; l != NULL; l = g_list_next(l)) {
				i = l->data;
				if (i->display) {
					clutter_actor_hide(i->display);
				}
			}	
			gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, TRUE);
			gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem_file_details),FALSE);
			gtk_widget_show(GTK_WIDGET(clutter));
			gtk_widget_show(GTK_WIDGET(fixed));
			gtk_widget_set_sensitive(menuitem_view, TRUE);
			fosfor_button_set_sensitive(FOSFOR_BUTTON(cfullscreen), TRUE);
			gtk_widget_set_size_request(GTK_WIDGET(fixed),video_width,video_height);
			gtk_window_resize(GTK_WINDOW(window),video_width,video_height + main_menu->allocation.height);
		} else {
			gtk_widget_show(GTK_WIDGET(clutter));
			gtk_widget_show(GTK_WIDGET(fixed));
			if (playlist != NULL) {
				i = playlist->data;			
				if (i != NULL)
					gtk_widget_set_size_request(GTK_WIDGET(fixed),clutter_actor_get_width(i->display) + 20.0 ,clutter_actor_get_height(i->display) + 20.0);
			} else {
				gtk_widget_set_size_request(GTK_WIDGET(fixed),320,120);
			}

			gtk_widget_set_sensitive(menuitem_view, FALSE);
			gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, TRUE);
			fosfor_button_set_sensitive(FOSFOR_BUTTON(cfullscreen), FALSE);
		}
	}
	
    if (!GTK_WIDGET_VISIBLE(window))
	    gtk_widget_show_all(window);
	if (embed_window)
		gtk_widget_hide(main_menu);

    return FALSE;
}

void on_menu_file_open_activate(GtkMenuItem *menuitem, gpointer data)
{
	GtkWidget *dialog;
	gchar *uri, *basename, *title;
	GtkRecentManager *recent_manager;
	GFile *file;
	
    dialog = gtk_file_chooser_dialog_new("Open File",
                                         GTK_WINDOW(window),
                                         GTK_FILE_CHOOSER_ACTION_OPEN,
                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                         GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);

	gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog),FALSE);
	
	if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
        uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
        if (uri) {
        	video_width = 0;
        	video_height = 0;
			media_aspect = 0.0;
			gtk_widget_hide_all(GTK_WIDGET(fixed));
	   		printf("playing %s \n",uri);

			clear_playlist();
			gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem_file_details),FALSE);			
			clutter_actor_animate(media, CLUTTER_LINEAR, 100, "scale-x", 1.0, "scale-y", 1.0, NULL);
			add_item_to_playlist(uri);
			gst_element_set_state(pipeline, GST_STATE_NULL);
			g_object_set(G_OBJECT(pipeline),"uri",uri,NULL);
			gst_element_set_state(pipeline, GST_STATE_PLAYING);
			file = g_file_new_for_uri(uri);
			basename = g_file_get_basename(file);
			g_object_unref(file);
			title = g_strdup_printf(_("%s - Fosfor"), basename);
			gtk_window_set_title(GTK_WINDOW(window),title);
			g_free(title);
			g_free(basename);

			recent_manager = gtk_recent_manager_get_default();
			gtk_recent_manager_add_item(recent_manager, uri);
			
			g_free(uri);
			
			if (get_playing(pipeline)) {
				fosfor_button_set_from_stock(FOSFOR_BUTTON(cplay_pause), GTK_STOCK_MEDIA_PAUSE, GTK_ICON_SIZE_MENU);
				fosfor_tracker_set_message(FOSFOR_TRACKER(ctracker),_("Playing"));
			} else {
				fosfor_button_set_from_stock(FOSFOR_BUTTON(cplay_pause), GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_MENU);
				fosfor_tracker_set_message(FOSFOR_TRACKER(ctracker),_("Paused"));
			}			
		}
	}
	gtk_widget_destroy(dialog);
}

void on_forward_clicked(FosforButton *button, gpointer data)
{
	gdouble seconds = 0.0;
	
	if (get_playing(pipeline) && can_seek) {

		seconds = get_progress(pipeline) * duration + 10.0;
		set_progress(pipeline, seconds / duration);
		
	}
}

void on_rewind_clicked(FosforButton *button, gpointer data)
{
	gdouble seconds = 0.0;
	
	if (get_playing(pipeline) && can_seek) {

		seconds = get_progress(pipeline) * duration - 10.0;
		set_progress(pipeline, seconds / duration);
		
	}
}

void on_stop_clicked(FosforButton *button, gpointer data)
{
	if (get_playing(pipeline)) {
		set_playing(pipeline,FALSE);
		set_progress(pipeline,0.0);
	}
	fosfor_button_set_from_stock(FOSFOR_BUTTON(cplay_pause), GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_MENU);
	fosfor_tracker_set_value(FOSFOR_TRACKER(ctracker),0);
	fosfor_tracker_set_message(FOSFOR_TRACKER(ctracker),_("Stopped"));

}


void on_play_pause_clicked(FosforButton *button, gpointer data)
{
	set_playing(pipeline,!get_playing(pipeline));
	if (get_playing(pipeline)) {
		fosfor_button_set_from_stock(FOSFOR_BUTTON(cplay_pause), GTK_STOCK_MEDIA_PAUSE, GTK_ICON_SIZE_MENU);
		fosfor_tracker_set_message(FOSFOR_TRACKER(ctracker),_("Playing"));
	} else {
		fosfor_button_set_from_stock(FOSFOR_BUTTON(cplay_pause), GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_MENU);
		fosfor_tracker_set_message(FOSFOR_TRACKER(ctracker),_("Paused"));
	}			
		
}

void on_button_release_event(ClutterActor *actor, ClutterEvent *event, gpointer data)
{
	if (event->type == CLUTTER_BUTTON_RELEASE) {
		if (((ClutterButtonEvent *)event)->button == 1) {
			on_play_pause_clicked((FosforButton *)cplay_pause, data);
		}
	}
}

void on_volume_percentage_changed(FosforVolume *volume, gdouble value, gpointer data)
{
	//printf("volume is %f\n",value);
	//gst_stream_volume_set_volume(GST_STREAM_VOLUME(pipeline),GST_STREAM_VOLUME_FORMAT_CUBIC, value * 10.0);
	value = CLAMP(value, 0.0, 1.0);
	//printf("volume = %f\n",value);
	gst_stream_volume_set_volume (GST_STREAM_VOLUME (pipeline), GST_STREAM_VOLUME_FORMAT_CUBIC, value);
	
}	

void on_fullscreen_clicked(FosforButton *button, gpointer data)
{
	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem_view_fullscreen),!isfullscreen);

}

void on_menuitem_view_fullscreen_toggled(GtkMenuItem * menuitem, void *data)
{
	GdkWindow *window_container = NULL;
	GtkWidget *other_window;
	
	if (isfullscreen) {
		gtk_window_unfullscreen(GTK_WINDOW(window));

		if (embed_window) {
		    window_container = gdk_window_foreign_new(embed_window);
		    if (GTK_WIDGET_MAPPED(window))
		        gtk_widget_unmap(window);

		    gdk_window_reparent(window->window, window_container, 0, 0);
			gtk_widget_map(window);
		} else {
			gtk_widget_show_all(main_menu);
		}
		
		isfullscreen = FALSE;
	} else {
		if (embed_window) {
		    if (GTK_WIDGET_MAPPED(window))
		        gtk_widget_unmap(window);

		    gdk_window_reparent(window->window, NULL, 0, 0);
			gtk_widget_map(window);
		}
		
		gtk_widget_hide_all(main_menu);
		gtk_window_fullscreen(GTK_WINDOW(window));
		isfullscreen = TRUE;
	}
}

void on_menuitem_view_controls_toggled(GtkMenuItem * menuitem, void *data)
{
	idledata->showcontrols = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem_view_controls));
	set_show_controls(idledata);
	
}   


gboolean on_fixed_configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data)
{
	video_width = event->width;
	video_height = event->height;
	resize_window(NULL);

	return FALSE;
}

gboolean on_fixed_enter_notify_event(GtkWidget *widget, GdkEventCrossing *event, gpointer data) 
{
	mouse_over_fixed = TRUE;
	return FALSE;
}

gboolean on_fixed_leave_notify_event(GtkWidget *widget, GdkEventCrossing *event, gpointer data) 
{
	mouse_over_fixed = FALSE;
	gdk_window_set_cursor(window->window, NULL);
	clutter_actor_animate(control_group, CLUTTER_LINEAR, 200, "opacity", 0x00, NULL);
	return FALSE;
}

gboolean on_window_scroll_event(GtkWidget *widget, GdkEventScroll * event, gpointer data)
{
    GTimeVal currenttime;

    g_get_current_time(&currenttime);
    last_movement_time = currenttime.tv_sec;
    make_mouse_visible(NULL);

	return FALSE;
}

gboolean on_tracker_percentage_changed(GtkWidget * widget, gdouble percent, void *data)
{
	
	if (get_playing(pipeline) && can_seek) {
		set_progress(pipeline, percent);
	}

	return FALSE;
}	

void on_control_group_paint(ClutterActor *actor, gpointer data) {

	gdouble width = clutter_actor_get_width(actor);
	gdouble height = clutter_actor_get_height(actor);
	cairo_t *cr;

	clutter_cairo_texture_set_surface_size(CLUTTER_CAIRO_TEXTURE(control_background), width, height);
	clutter_cairo_texture_clear(CLUTTER_CAIRO_TEXTURE(control_background));

	cr = clutter_cairo_texture_create(CLUTTER_CAIRO_TEXTURE(control_background));

  	/* draw on the context */
	cairo_set_source_rgb(cr, 1.0,1.0,1.0);
	cairo_set_line_width(cr, 2.0);
	cairo_rounded_rectangle(cr, 0.0,0.0, width ,height, 10.0);

	cairo_fill_preserve(cr);

	cairo_stroke(cr);	
	cairo_destroy (cr);

}

void on_fixed_size_allocate(GtkWidget *widget,  GtkAllocation *allocation, gpointer data)
{
	gdouble window_aspect;
	gint new_width, new_height, new_x, new_y;
	gdouble actor_aspect;
	gint a_width, a_height;

	a_width = allocation->width;
	if (idledata->showcontrols) {
		a_height = allocation->height; // - clutter_actor_get_height(control_cbox);
	} else {
		a_height = allocation->height;
	}	
	
	window_aspect = (gdouble)a_width / (gdouble)a_height;
	actor_aspect = media_aspect;

	if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem_view_aspect_default)))
	    actor_aspect = media_aspect;
	if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem_view_aspect_16x9)))
	    actor_aspect = 16.0 / 9.0;
	if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem_view_aspect_16x10)))
	    actor_aspect = 16.0 / 10.0;
	if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem_view_aspect_4x3)))
	    actor_aspect = 4.0 / 3.0;
	if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem_view_aspect_follow)))
	    actor_aspect = window_aspect;

	
	if (actor_aspect > window_aspect) {
		new_width = a_width;
		new_height = a_width / actor_aspect;
	} else {
		new_width = a_height * actor_aspect;
		new_height = a_height;
	}
	new_x = (a_width - new_width) / 2;
	new_y = (a_height - new_height) / 2;
	
	//video_width = new_width;
	//video_height = new_height;
    clutter_actor_set_size(stage, allocation->width,allocation->height);
    clutter_actor_set_size(media, new_width,new_height);
	clutter_actor_set_anchor_point(media, new_width / 2.0, new_height / 2.0);
	//clutter_actor_set_position(media, new_x,new_y);
	clutter_actor_set_position(media, a_width / 2.0, a_height / 2.0);
	clutter_actor_set_width(ctracker, 20.0);
	clutter_actor_set_width(control_cbox, MIN(a_width, 512));
	clutter_actor_set_position(control_group, MAX(a_width / 2.0 - MIN(a_width, 512) / 2.0, 0.0), a_height - clutter_actor_get_height(control_group));
    gtk_widget_set_size_request(clutter, allocation->width, allocation->height);
	
}	

gboolean on_window_key_press_event(GtkWidget * widget, GdkEventKey * event, gpointer user_data)
{
	gdouble scale_x, scale_y;
	gfloat angle, x=0.0,y=0.0,z=0.0;
	
    if (event->state == (event->state & (~GDK_CONTROL_MASK))) {
		switch (event->keyval) {
			case GDK_f:
			case GDK_F:
				gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem_view_fullscreen),!isfullscreen);
				break;
			case GDK_KP_Add:
				// zoom in
				clutter_actor_get_scale(media, &scale_x, &scale_y);
				scale_x += 0.1;
				scale_y += 0.1;
				clutter_actor_animate(media, CLUTTER_LINEAR, 100, "scale-x", scale_x, "scale-y", scale_y, NULL);
				break;
			case GDK_KP_Subtract:
				// zoom out
				clutter_actor_get_scale(media, &scale_x, &scale_y);
				scale_x -= 0.1;
				scale_y -= 0.1;
				scale_x = (scale_x < 0.1)?0.1:scale_x;
				scale_y = (scale_y < 0.1)?0.1:scale_y;
				clutter_actor_animate(media, CLUTTER_LINEAR, 100, "scale-x", scale_x, "scale-y", scale_y, NULL);
				break;
			case GDK_KP_Enter:
				clutter_actor_animate(media, CLUTTER_LINEAR, 100, "scale-x", 1.0, "scale-y", 1.0, NULL);
				clutter_actor_set_rotation(media,CLUTTER_X_AXIS, 0.0, x,y,z);
				clutter_actor_set_rotation(media,CLUTTER_Y_AXIS, 0.0, x,y,z);
				clutter_actor_set_rotation(media,CLUTTER_Z_AXIS, 0.0, x,y,z);
				return TRUE;  // True means don't process this key anymore
				break;
			case GDK_Escape:
				if (isfullscreen) {
					gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem_view_fullscreen),!isfullscreen);
				} else {
					gtk_main_quit();
				}
				break;
			case GDK_space:
				on_play_pause_clicked(FOSFOR_BUTTON(cplay_pause),NULL);
				return TRUE;
				break;
			case GDK_KP_9:
				angle = clutter_actor_get_rotation(media,CLUTTER_Z_AXIS, &x,&y,&z);
				clutter_actor_set_rotation(media,CLUTTER_Z_AXIS, angle + 5.0, x,y,z);
				break;
			case GDK_KP_7:
				angle = clutter_actor_get_rotation(media,CLUTTER_Z_AXIS, &x,&y,&z);
				clutter_actor_set_rotation(media,CLUTTER_Z_AXIS, angle - 5.0,  x,y,z);
				break;
			case GDK_KP_6:
				angle = clutter_actor_get_rotation(media,CLUTTER_Y_AXIS, &x,&y,&z);
				clutter_actor_set_rotation(media,CLUTTER_Y_AXIS, angle + 5.0, x,y,z);
				break;
			case GDK_KP_4:
				angle = clutter_actor_get_rotation(media,CLUTTER_Y_AXIS, &x,&y,&z);
				clutter_actor_set_rotation(media,CLUTTER_Y_AXIS, angle - 5.0, x,y,z);
				break;
			case GDK_KP_8:
				angle = clutter_actor_get_rotation(media,CLUTTER_X_AXIS, &x,&y,&z);
				clutter_actor_set_rotation(media,CLUTTER_X_AXIS, angle + 5.0, x,y,z);
				break;
			case GDK_KP_2:
				angle = clutter_actor_get_rotation(media,CLUTTER_X_AXIS, &x,&y,&z);
				clutter_actor_set_rotation(media,CLUTTER_X_AXIS, angle - 5.0, x,y,z);
				break;
			default:
				break;
		}

	}
	return FALSE;
}

gboolean on_window_delete_event(GtkWidget * widget, GdkEvent * event, void *data)
{
	//clutter_main_quit();
	gtk_main_quit();
	return TRUE;
}

void notify_caps_callback(GObject *obj, GParamSpec * pspec, gpointer data)
{
	GstPad *pad = GST_PAD (obj);
	GstStructure *s;
	GstCaps *caps;
	const GValue *ratio;

	if (!(caps = gst_pad_get_negotiated_caps (pad))) {
		//printf("no negotiated caps\n");
		return;
	}

	/* Get video decoder caps */
	s = gst_caps_get_structure (caps, 0);
	if (s) {
		// printf("Structure: %s\n", gst_structure_to_string(s));
		gst_structure_get_int(s,"width",&video_width);
		gst_structure_get_int(s,"height",&video_height);

		if (video_width > 0 && video_height > 0) {

			ratio = gst_structure_get_value(s, "pixel-aspect-ratio");
			if (ratio) {
				// printf("%i by %i \n",gst_value_get_fraction_numerator(ratio), gst_value_get_fraction_denominator(ratio));
				video_width = video_width * gst_value_get_fraction_numerator(ratio) / gst_value_get_fraction_denominator(ratio);
			} 
			media_aspect = (gdouble)video_width / (gdouble)video_height;
			// printf("Notify Caps Media Size = %i x %i\n",video_width,video_height);
		}
		
		resize_window(NULL);
	}

	gst_caps_unref (caps);
}


void bus_message_callback(GstBus * bus, GstMessage * message, gpointer data)
{
    GstMessageType msg_type;
    // const gchar *msg_name;
    GstPad *pad = NULL;
    GstCaps *caps;
	GstTagList *tag_list;
	GList *l;
	ListItem *li;
	ListItem *item = (ListItem *)data;
	gint n_video, n_audio, i;
	gdouble value;
	// GstElement *dvdsrc;
	// const gchar *type_name = NULL;    
	GstQuery *query;
	GstState old_state, new_state;
	gint64 media_length;
	gchar *src_name;
	
    msg_type = GST_MESSAGE_TYPE (message);
	src_name = gst_object_get_name (message->src);
    
    if (0) {
		printf("Handling %s message from element %s\n",
		    gst_message_type_get_name (msg_type), src_name);
	}
	
    switch (msg_type) {
        case GST_MESSAGE_APPLICATION:
			printf("application message\n");	
            break;
		case GST_MESSAGE_WARNING:
			printf("warning message\n");
			break;
		case GST_MESSAGE_TAG:
			// we only want the tags that are being loaded from the fakesink for now.
			if (item != NULL) {
				// printf("\nWe have some tags, now to parse them\n");

				gst_message_parse_tag (message, &tag_list);
  				//printf("Tags: %" GST_PTR_FORMAT, tag_list);	
				item->tags = gst_tag_list_merge (item->tags, tag_list, GST_TAG_MERGE_REPLACE);
				update_item_display(item);
				if (video_width == 0 && video_height == 0) {
					gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem_file_details),TRUE);
					clutter_actor_show(item->display);
				} else {
					gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem_file_details),FALSE);
				}		
			} else {
				//for debugging
				//gst_message_parse_tag (message, &tag_list);
  				//printf("Tags: %" GST_PTR_FORMAT, tag_list);	
			}		
			
			break;
		case GST_MESSAGE_EOS:
			// printf("eos message\n");
			g_object_notify (G_OBJECT(media), "progress");	

			for(l = playlist; l != NULL; l = g_list_next(l)) {
				li = l->data;
				if (li->display) {
					clutter_actor_hide(li->display);
				}
			}

	
			on_stop_clicked(NULL,NULL);
			gst_element_set_state(pipeline, GST_STATE_READY);

			break;

		case GST_MESSAGE_ELEMENT:
			/*
			
			if (message->structure)
			    type_name = gst_structure_get_name (message->structure);
			gchar *src_name = gst_object_get_name (message->src);
			printf("Handling %s message from element %s\n",
		    gst_message_type_get_name (msg_type), src_name);
			g_free (src_name);
			printf("type name = %s\n",type_name);
			printf("is it a navigation type = %i\n", GST_IS_NAVIGATION(message->src));

			if (g_strrstr(type_name,"GstNavigationMessage") != NULL) {
				printf("got a navigation message\n");
				GstNavigationMessageType nav_msg_type = gst_navigation_message_get_type (message);
				switch (nav_msg_type) {
					case GST_NAVIGATION_MESSAGE_MOUSE_OVER:
						printf("got mouse over\n");
						break;
					case GST_NAVIGATION_MESSAGE_COMMANDS_CHANGED:
						printf("got commands changed\n");
						has_navigation = TRUE;
						break;
					default:
						printf("something else\n");
				}
			}
			*/ 
			
			/*
			dvdsrc = gst_bin_get_by_interface (GST_BIN(message->src), GST_TYPE_NAVIGATION);
			if (dvdsrc)
				printf("GST Object Name is %s\n",GST_OBJECT_NAME(dvdsrc));

	
			if (GST_IS_NAVIGATION (dvdsrc)) {
				printf("Found navigation: %s", GST_OBJECT_NAME (dvdsrc));
			} else {
				printf("No navigation found\n");
			}						
			*/
			
			break;
		case GST_MESSAGE_ASYNC_DONE:
			if (g_strrstr(gst_object_get_name (message->src),"fakeplaybin")) {
				gst_element_set_state (GST_ELEMENT(message->src), GST_STATE_NULL);
				if (item != NULL) {
					// printf("Tags: %" GST_PTR_FORMAT "\n", item->tags);	
					update_item_display(item);
					if (video_width == 0 && video_height == 0) {
						gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem_file_details),TRUE);
						clutter_actor_show(item->display);
						resize_window(NULL);
					} else {
						gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem_file_details),FALSE);
					}			
				}
			}
			break;
		case GST_MESSAGE_STATE_CHANGED:

			// VIDEO SIZE is initialized here
			//printf("state changed, src = %s\n",src_name);
			

			if (g_strrstr(src_name,"pipeline")) {
				g_object_get (pipeline, "n-audio", &n_audio,"n-video", &n_video, NULL);

				if (n_audio > 0) {
					if (GST_IS_STREAM_VOLUME(message->src)) {
						value = gst_stream_volume_get_volume (GST_STREAM_VOLUME (message->src),
						                          GST_STREAM_VOLUME_FORMAT_CUBIC);
						printf("%s volume is %f\n", src_name, value);
						fosfor_volume_set_value(FOSFOR_VOLUME(cvolume),value);
					}
				}
			}

			
			if (g_strrstr(src_name,"fakesink")) {
				g_object_get (pipeline, "n-audio", &n_audio,"n-video", &n_video, NULL);
				//printf("audio = %i video = %i\n", n_audio, n_video);
			
				if (n_video > 0) {
					for (i = 0; i < n_video && pad == NULL; i++) {
					  g_signal_emit_by_name (G_OBJECT(pipeline), "get-video-pad", i, &pad);
					}
		            if (GST_IS_PAD(pad)) {
		                g_signal_connect(G_OBJECT(pad),"notify::caps", 
		                                 G_CALLBACK(notify_caps_callback), NULL);
		                caps = gst_pad_get_negotiated_caps(pad);
		                if (caps) {
							// printf("notify that we have some caps\n");
							g_object_notify(G_OBJECT(pad),"caps");
		                    gst_caps_unref(caps);
		                } else {
		                    //printf("don't have any caps\n");
		                }
		                gst_object_unref(pad);
		            } else {
		                printf("failed to get pad\n");
		            }
				}			
			}
			
			gst_message_parse_state_changed (message, &old_state, &new_state, NULL);

			if (old_state == GST_STATE_READY &&  new_state == GST_STATE_PAUSED) {
				can_seek = FALSE;
				query = gst_query_new_seeking (GST_FORMAT_TIME);
			
				if (gst_element_query (pipeline, query)) {
					gst_query_parse_seeking (query, NULL, &can_seek,NULL,NULL);
					// printf("can seek = %i\n",can_seek);
				}
				gst_query_unref(query);
			
			}

			query = gst_query_new_duration(GST_FORMAT_TIME);
			if (gst_element_query(pipeline, query)) {
				gst_query_parse_duration(query, NULL, &media_length);
				duration = (gdouble)media_length / GST_SECOND;
				// printf("duration = %.02f\n",duration);
			}
			gst_query_unref(query);
			
			break;
        default:
			//printf("Unknown Message type of %i %s\n",msg_type, gst_message_type_get_name (msg_type));
            break;
    }

	g_free (src_name);

}

void stream_info_notify_callback(GObject * obj, GParamSpec * pspec, gpointer data)
{
  GstMessage *msg;

  /* we're being called from the streaming thread, so don't do anything here */
  msg = gst_message_new_application (GST_OBJECT (obj),
      gst_structure_new ("notify-streaminfo", NULL));
  gst_element_post_message (GST_ELEMENT(obj), msg);
}

void element_changed_callback(GstElement * obj, gpointer data)
{
  GstMessage *msg;

  //printf("element changed\n");
  /* we're being called from the streaming thread, so don't do anything here */
  msg = gst_message_new_application (GST_OBJECT (obj),
      gst_structure_new ("stream-changed", NULL));
  gst_element_post_message (GST_ELEMENT(obj), msg);
}


void video_sink_element_added(GstBin *video_sink, GstElement *element, gpointer data)
{
	/*
	printf("element name is %s\n", GST_ELEMENT_NAME(element));
	printf("is it a navigation type = %i\n", GST_IS_NAVIGATION(element));
	if (GST_IS_BIN (video_sink)) {
		printf("Retrieving navigation from bin ...\n");
		element = gst_bin_get_by_interface (GST_BIN (video_sink), GST_TYPE_NAVIGATION);
	} else {
		element = gst_object_ref(video_sink);
	}

	if (GST_IS_NAVIGATION (element)) {
		printf("Found navigation: %s\n", GST_OBJECT_NAME (element));
	} else {
		printf("No navigation found\n");
		if (element)
			gst_object_unref (element);
	}	
	*/
}

void make_mouse_invisible()
{
    GdkColor cursor_color = { 0, 0, 0, 0 };
    GdkPixmap *cursor_source;
    GdkCursor *cursor;
    GTimeVal currenttime;

    g_get_current_time(&currenttime);
    g_time_val_add(&currenttime, -3 * G_USEC_PER_SEC);

	
	if (mouse_over_fixed && last_movement_time > 0 && currenttime.tv_sec > last_movement_time) {
		cursor_source = gdk_pixmap_new(NULL, 1, 1, 1);
		cursor =
		    gdk_cursor_new_from_pixmap(cursor_source, cursor_source, &cursor_color,
		                               &cursor_color, 0, 0);
		gdk_pixmap_unref(cursor_source);
		gdk_window_set_cursor(window->window, cursor);
		gdk_cursor_unref(cursor);
		clutter_actor_animate(control_group, CLUTTER_LINEAR, 200, "opacity", 0x00, NULL);

	}
}

gboolean make_mouse_visible(gpointer data)
{
	gdk_window_set_cursor(window->window, NULL);
	if (idledata->showcontrols)
		clutter_actor_animate(control_group, CLUTTER_LINEAR, 200, "opacity", 0xcc, NULL);

    return FALSE;
}

gboolean update_gui(gpointer data)
{
	
    if (get_playing(pipeline)) {
		fosfor_tracker_set_duration(FOSFOR_TRACKER(ctracker),duration);
		fosfor_tracker_set_value(FOSFOR_TRACKER(ctracker),get_progress(pipeline) * duration);
		fosfor_tracker_set_message(FOSFOR_TRACKER(ctracker),_("Playing"));		
		make_mouse_invisible();
	}
    return TRUE;
}


void on_menuitem_file_details_toggled(GtkCheckMenuItem *checkmenuitem, gpointer data)
{
	ListItem *item;
	
	if (gtk_check_menu_item_get_active(checkmenuitem)) {
		if (playlist) {
			item = playlist->data;
			clutter_actor_show(item->display);
		}
	} else {
		if (playlist) {
			item = playlist->data;
			clutter_actor_hide(item->display);
		}
	}	

}

void on_menuitem_file_open_recent_activate(GtkMenuItem *menuitem, gpointer data)
{

}

void menuitem_open_recent_item_activated(GtkRecentChooser * chooser, gpointer data)
{
	gchar *uri, *basename, *title;	
	GFile *file;
	
	uri = gtk_recent_chooser_get_current_uri(chooser);
    if (uri) {
    	video_width = 0;
    	video_height = 0;
		media_aspect = 0.0;
		gtk_widget_hide_all(GTK_WIDGET(fixed));
   		printf("playing %s \n",uri);

		clear_playlist();
		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem_file_details),FALSE);			
		clutter_actor_animate(media, CLUTTER_LINEAR, 100, "scale-x", 1.0, "scale-y", 1.0, NULL);
		add_item_to_playlist(uri);
		gst_element_set_state(pipeline, GST_STATE_NULL);
		g_object_set(G_OBJECT(pipeline),"uri",uri,NULL);
		gst_element_set_state(pipeline, GST_STATE_PLAYING);
		file = g_file_new_for_uri(uri);
		basename = g_file_get_basename(file);
		g_object_unref(file);
		title = g_strdup_printf(_("%s - Fosfor"), basename);
		gtk_window_set_title(GTK_WINDOW(window),title);
		g_free(title);
		g_free(basename);

		g_free(uri);
		if (get_playing(pipeline)) {
			fosfor_button_set_from_stock(FOSFOR_BUTTON(cplay_pause), GTK_STOCK_MEDIA_PAUSE, GTK_ICON_SIZE_MENU);
			fosfor_tracker_set_message(FOSFOR_TRACKER(ctracker),_("Playing"));
		} else {
			fosfor_button_set_from_stock(FOSFOR_BUTTON(cplay_pause), GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_MENU);
			fosfor_tracker_set_message(FOSFOR_TRACKER(ctracker),_("Paused"));
		}			
	}

}

void on_menuitem_file_quit_activate(GtkMenuItem *menuitem, gpointer data)
{
	on_window_delete_event(NULL,NULL,NULL);
}

static void about_url_hook(GtkAboutDialog * about, const char *link, gpointer data)
{
    GError *error = NULL;

    if (!gtk_show_uri(gtk_widget_get_screen(GTK_WIDGET(about)), link,
                      gtk_get_current_event_time(), &error)) {
        g_error_free(error);
    }
}

void on_menuitem_help_about_activate(GtkMenuItem *menuitem, gpointer data)
{
    gchar *authors[] = { "Kevin DeKorte", NULL };
    gtk_about_dialog_set_url_hook(about_url_hook, NULL, NULL);
    gtk_show_about_dialog(GTK_WINDOW(window), "name", _("Fosfor"), "authors", authors,
                          "copyright", "Copyright © 2007,2008 Kevin DeKorte", "comments",
                          _("A media player for GNOME that uses Clutter and GStreamer"), "version", VERSION,
                          "license",
                          _
                          ("Fosfor is free software; you can redistribute it and/or modify it under\nthe terms of the GNU General Public License as published by the Free\nSoftware Foundation; either version 2 of the License, or (at your option)\nany later version."
                           "\n\nFosfor is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\nFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\nmore details."
                           "\n\nYou should have received a copy of the GNU General Public License along with\nFosfor if not, write to the\n\nFree Software Foundation, Inc.,\n51 Franklin St, Fifth Floor\nBoston, MA 02110-1301 USA")


                          ,
                          "website", "http://code.google.com/p/fosfor/",
                          "translator-credits","", NULL);

}

void on_menuitem_view_size_natural_activate(GtkMenuItem *menuitem, gpointer data)
{
	clutter_actor_animate(media, CLUTTER_LINEAR, 100, "scale-x", 1.0, "scale-y", 1.0, NULL);
	gtk_window_resize(GTK_WINDOW(window),video_width,video_height + main_menu->allocation.height);
}

void on_menuitem_view_size_double_activate(GtkMenuItem *menuitem, gpointer data)
{
	clutter_actor_animate(media, CLUTTER_LINEAR, 100, "scale-x", 1.0, "scale-y", 1.0, NULL);
	gtk_window_resize(GTK_WINDOW(window),video_width * 2 ,(video_height * 2)  + main_menu->allocation.height);
}

gboolean on_window_drag_data_received(GtkWidget * widget, GdkDragContext * dc,
                       gint x, gint y, GtkSelectionData * selection_data,
                       guint info, guint t, gpointer data)
{
	gchar **list;
	gchar *basename, *title;	
	GtkRecentManager *recent_manager;
	GFile *file;
	
    if (selection_data == NULL)
        return FALSE;
    if (selection_data->length < 0)
        return FALSE;
	
	if ((info == DRAG_INFO_0) || (info == DRAG_INFO_1) || (info == DRAG_INFO_2)) {
        list = g_uri_list_extract_uris((const gchar *) selection_data->data);

        if (list[0]) {
        	video_width = 0;
        	video_height = 0;
			media_aspect = 0.0;
			gtk_widget_hide_all(GTK_WIDGET(fixed));
	   		printf("playing %s \n",list[0]);

			clear_playlist();
			gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem_file_details),FALSE);			
			clutter_actor_animate(media, CLUTTER_LINEAR, 100, "scale-x", 1.0, "scale-y", 1.0, NULL);
			add_item_to_playlist(list[0]);
			gst_element_set_state(pipeline, GST_STATE_NULL);
			g_object_set(G_OBJECT(pipeline),"uri",list[0],NULL);
			gst_element_set_state(pipeline, GST_STATE_PLAYING);
			file = g_file_new_for_uri(list[0]);
			basename = g_file_get_basename(file);
			g_object_unref(file);
			title = g_strdup_printf(_("%s - Fosfor"), basename);
			gtk_window_set_title(GTK_WINDOW(window),title);
			g_free(title);
			g_free(basename);
			
			recent_manager = gtk_recent_manager_get_default();
			gtk_recent_manager_add_item(recent_manager, list[0]);

			if (get_playing(pipeline)) {
				fosfor_button_set_from_stock(FOSFOR_BUTTON(cplay_pause), GTK_STOCK_MEDIA_PAUSE, GTK_ICON_SIZE_MENU);
				fosfor_tracker_set_message(FOSFOR_TRACKER(ctracker),_("Playing"));
			} else {
				fosfor_button_set_from_stock(FOSFOR_BUTTON(cplay_pause), GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_MENU);
				fosfor_tracker_set_message(FOSFOR_TRACKER(ctracker),_("Paused"));
			}	
			g_strfreev(list);
		}
		
	}
	
	return TRUE;
}

gboolean on_window_motion_notify_event(GtkWidget * widget, GdkEventMotion * event, gpointer data)
{
    GTimeVal currenttime;

    g_get_current_time(&currenttime);
    last_movement_time = currenttime.tv_sec;
    make_mouse_visible(NULL);
	
    return FALSE;
}

gboolean set_play(void *data) {

    if (!get_playing(pipeline)) {
		set_playing(pipeline,TRUE);
	}
	
	return FALSE;

}

gboolean set_pause(void *data){
    if (get_playing(pipeline)) {
		set_playing(pipeline,FALSE);
	}
	return FALSE;
}

gboolean set_stop(void *data){

	set_progress(pipeline, 0.0);
	set_playing(pipeline,FALSE);
	
	return FALSE;

}

gboolean set_ff(void *data){
	
	on_forward_clicked(NULL,NULL);
	return FALSE;

}

gboolean set_rew(void *data){

	on_rewind_clicked(NULL,NULL);
	return FALSE;

}

gboolean clear_playlist_and_play(gpointer data)
{
	printf("playing %s\n",(gchar *)data);
	fosfor_tracker_set_message(FOSFOR_TRACKER(ctracker),_("Playing"));
	g_object_set(G_OBJECT(pipeline),"uri",(gchar*)data,NULL);
	gst_element_set_state(pipeline, GST_STATE_PLAYING);
	if (get_playing(pipeline)) {
		fosfor_button_set_from_stock(FOSFOR_BUTTON(cplay_pause), GTK_STOCK_MEDIA_PAUSE, GTK_ICON_SIZE_MENU);
		fosfor_tracker_set_message(FOSFOR_TRACKER(ctracker),_("Playing"));
	} else {
		fosfor_button_set_from_stock(FOSFOR_BUTTON(cplay_pause), GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_MENU);
		fosfor_tracker_set_message(FOSFOR_TRACKER(ctracker),_("Paused"));
	}			
	
    return FALSE;
}

gboolean set_progress_text(void *data)
{
    IdleData *idle = (IdleData *) data;

    if (FOSFOR_IS_TRACKER(ctracker)) {
        fosfor_tracker_set_message(FOSFOR_TRACKER(ctracker), idle->progress_text);
    }
    return FALSE;
}

gboolean set_show_controls(void *data)
{
	if (idledata->showcontrols)
		clutter_actor_set_opacity(control_group, 0xcc);
	else
		clutter_actor_set_opacity(control_group, 0x00);
		

	return FALSE;
}

gboolean on_display_button_release_event(ClutterActor * actor, ClutterButtonEvent * event, gpointer data)
{
	printf("item display clicked\n");
	return FALSE;
}

void on_menuitem_view_aspect_toggled(GtkCheckMenuItem *checkmenuitem, gpointer data)
{
	on_fixed_size_allocate (GTK_WIDGET(fixed),&(GTK_WIDGET(fixed)->allocation), NULL);
}


void audio_tags_changed_callback(GstElement *playbin, gint stream_id, gpointer data)
{
	GList *l;

	l = get_lang_list_for_type(pipeline, "AUDIO");
	g_mutex_lock(menu_update_mutex);
	update_languages(l);
	g_mutex_unlock(menu_update_mutex);
}

void text_tags_changed_callback(GstElement *playbin, gint stream_id, gpointer data)
{
	GList *l;

	l = get_lang_list_for_type(pipeline, "TEXT");
	g_mutex_lock(menu_update_mutex);
	update_subtitles(l);
	g_mutex_unlock(menu_update_mutex);
}

void on_subtitle_activate(GtkMenuItem *menuitem, gpointer data)
{
	gint title = GPOINTER_TO_INT(data);
	gint flags;
	
	if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) {
		g_object_get (pipeline, "flags", &flags, NULL);

		if (title == -2) {
			flags &= ~GST_PLAY_FLAGS_TEXT;
			title = -1;
		} else {
			flags |= GST_PLAY_FLAGS_TEXT;
		}
		
		g_object_set(pipeline, "flags", flags, "current-text", title, NULL);
	}

}

void update_subtitles(GList *list)
{
	GList *l;
	GtkWidget *menuitem;
	gint i = 0;
	gint title;
	GSList *group = NULL;
	gint flags;
	
	if (GTK_IS_WIDGET(menu_subtitles))
		gtk_widget_destroy(menu_subtitles);

	menu_subtitles = gtk_menu_new();
	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem_select_subtitle), menu_subtitles);

	g_object_get(pipeline, "current-text", &title, NULL);
	g_object_get (pipeline, "flags", &flags, NULL);
	if ((flags & GST_PLAY_FLAGS_TEXT) == 0)
		title = -2;
	
	menuitem = gtk_radio_menu_item_new_with_label(group,_("None"));
	group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem));
	if (title == -2)
		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu_subtitles),menuitem);
	g_signal_connect(menuitem,"activate", G_CALLBACK(on_subtitle_activate), GINT_TO_POINTER(-2));

	menuitem = gtk_radio_menu_item_new_with_label(group,_("Default"));
	group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem));
	if (title == -1)
		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu_subtitles),menuitem);
	g_signal_connect(menuitem,"activate", G_CALLBACK(on_subtitle_activate), GINT_TO_POINTER(-1));

	if (list != NULL) {
		for (l = g_list_first(list); l != NULL; l = g_list_next(l)) {
			menuitem = gtk_radio_menu_item_new_with_label(group,(gchar *)(l->data));
			group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem));
			gtk_menu_shell_append(GTK_MENU_SHELL(menu_subtitles),menuitem);
			if (i == title)
				gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
			g_signal_connect(menuitem,"activate", G_CALLBACK(on_subtitle_activate), GINT_TO_POINTER(i++));
		}
	}	

	gtk_widget_show_all(menu_subtitles);

}

void on_language_activate(GtkMenuItem *menuitem, gpointer data)
{
	gint title = GPOINTER_TO_INT(data);
	gint flags;
	
	
	if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) {
		g_object_get (pipeline, "flags", &flags, NULL);

		if (title == -2) {
			flags &= ~GST_PLAY_FLAGS_AUDIO;
			title = -1;
		} else {
			flags |= GST_PLAY_FLAGS_AUDIO;
		}
		g_object_set(pipeline, "flags", flags, "current-audio", title, NULL);
	}
	
}

void update_languages(GList *list)
{
	GList *l;
	GtkWidget *menuitem;
	gint i = 0;
	gint title;
	GSList *group = NULL;
	gint flags;

	if (GTK_IS_WIDGET(menu_languages))
		gtk_widget_destroy(menu_languages);

	menu_languages = gtk_menu_new();
	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem_select_audio), menu_languages);

	g_object_get(pipeline, "current-audio", &title, NULL);
	g_object_get (pipeline, "flags", &flags, NULL);
	if ((flags & GST_PLAY_FLAGS_AUDIO) == 0)
		title = -2;

	/*
	menuitem = gtk_radio_menu_item_new_with_label(group,_("None"));
	group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem));
	gtk_menu_shell_append(GTK_MENU_SHELL(menu_languages),menuitem);
	if (title == -2) {
		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
	}
	g_signal_connect(menuitem,"activate", G_CALLBACK(on_language_activate), GINT_TO_POINTER(-2));
	*/
	
	menuitem = gtk_radio_menu_item_new_with_label(group,_("Default"));
	group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem));
	gtk_menu_shell_append(GTK_MENU_SHELL(menu_languages),menuitem);
	if (title == -1) {
		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
	}
	g_signal_connect(menuitem,"activate", G_CALLBACK(on_language_activate), GINT_TO_POINTER(-1));

	if (list != NULL) {
		for (l = g_list_first(list); l != NULL; l = g_list_next(l)) {
			menuitem = gtk_radio_menu_item_new_with_label(group,(gchar *)(l->data));
			group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem));
			gtk_menu_shell_append(GTK_MENU_SHELL(menu_languages),menuitem);
			if (i == title) {
				gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
			}
			g_signal_connect(menuitem,"activate", G_CALLBACK(on_language_activate), GINT_TO_POINTER(i++));
		}
	}	

	gtk_widget_show_all(menu_languages);

}